/******************************************************************************
    myBoard is a port of MacOS X dashboard application for windows.
    Copyright (C) 2007,2008  by Yann ALET
    Email : yann.alet@gmail.com

    myBoard is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    myBard is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
****************************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Threading;

namespace myBoard.CalendarNS
{
    public class Cal : ObservableCollection<DateTime>,INotifyPropertyChanged
    {
        private List<string> _weekDays;
        private DateTime _activeDate;
        private DateTime _today;
        private DispatcherTimer _updateTimer;

        public DateTime Today
        {
            get { return _today; }            
        }

        public DateTime ActiveDate
        {
            get { return _activeDate; }
        }

        public string ActiveMonth
        {
            get
            {
                return _activeDate.ToString("Y").Replace(',',' ').ToLower();
            }
        }

        public string DayOfTheWeek
        {
            get
            {
                return _today.ToString("dddd").ToLower();
            }
        }
        
        public List<string> WeekDays
        {
            get { return _weekDays; }
        }

        public Cal()
        {
            _activeDate = DateTime.Now;
            _today = DateTime.Now;
            _updateTimer = new DispatcherTimer();
            _updateTimer.Interval = new TimeSpan(0, 1, 0);
            _updateTimer.Tick += new EventHandler(UpdateTimer_Tick);
            
            UpdateCalendar();

            _weekDays = new List<string>();
            IFormatProvider culture = System.Globalization.CultureInfo.CurrentCulture;
            for (int i = 0; i < 7; i++)
            {
                DateTime d = new DateTime(2007, 09, 3).AddDays(i);
                string[] days = d.GetDateTimeFormats('D', culture);
                _weekDays.Add(days[0].Substring(0, 1).ToUpper());
            }

            _updateTimer.Start();
        }

        void UpdateTimer_Tick(object sender, EventArgs e)
        {
            if (_today.Month != DateTime.Now.Month)
            {
                _today = DateTime.Now;
                _activeDate = DateTime.Now;
                UpdateCalendar();
            }
            _today = DateTime.Now;
            if(PropertyChanged!=null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("Today"));
                PropertyChanged(this, new PropertyChangedEventArgs("DayOfTheWeek"));
            }            
        }

        public void GotoNextMonth()
        {
            _activeDate = _activeDate.AddMonths(1);
            UpdateCalendar();
        }

        public void GotoPreviousMonth()
        {
            _activeDate = _activeDate.AddMonths(-1);
            UpdateCalendar();            
        }

        private void UpdateCalendar()
        {
            this.Clear();
            int nbOfDaysInMonth = DateTime.DaysInMonth(_activeDate.Year, _activeDate.Month);
            for (int i = 1; i <= nbOfDaysInMonth; i++)
            {
                DateTime day = new DateTime(_activeDate.Year, _activeDate.Month, i);
                this.Add(day);
            }

            DateTime previousDay = new DateTime(_activeDate.Year, _activeDate.Month, 1);
            if (previousDay.DayOfWeek != DayOfWeek.Monday)
            {
                for (int i = 7; i > 0; i--)
                {
                    previousDay = previousDay.AddDays(-1);
                    this.Insert(0, previousDay);
                    if (previousDay.DayOfWeek == DayOfWeek.Monday)
                        break;                    
                }
            }

            int nbOfDays = this.Count;
            
            if (nbOfDays < 42)
            {
                for (int i = 1; i <= 42 - nbOfDays; i++)
                {
                    this.Add(this[this.Count-1].AddDays(1));
                }                    
            }
            if(PropertyChanged!=null)
                PropertyChanged(this, new PropertyChangedEventArgs("ActiveMonth"));
        }

        private string GetDayName(DayOfWeek day)
        {
            for (int i = 0; i < 7; i++)
            {
                DateTime d = new DateTime(2007, 09, 3).AddDays(i);
                if (d.DayOfWeek == day)
                    return d.ToString("dddd");
            }
            return string.Empty;
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}
